// 每⼀个Connection对连接进⾏管理，最终都不可避免需要涉及到应用层协议的处理，因此在
// Connection中需要设置协议处理的上下⽂来控制处理节奏。但是应用层协议千千万，为了降低耦合
// 度，这个协议接收解析上下⽂就不能有明显的协议倾向，它可以是任意协议的上下文信息，因此就需
// 要⼀个通用的类型来保存各种不同的数据结构。

#include <iostream>
#include <memory>
#include <algorithm>
#include <utility>
#include <string>
#include <cassert>
#include <typeinfo>
#include <unistd.h>
#include <any>


class Any
{
public:
    Any():_content(nullptr){}
    template <typename T>
    Any(const T& val):_content(new placeholder<T>(val)){}
    Any(const Any&other):_content(other._content?other._content->clone():nullptr){}
    ~Any() {delete _content; }

    //获取对象保存的数据的指针
    template<typename T>
    T * get()
    {
        //类型和保存的类型必须一致
        assert(typeid(T) == _content->type());
        return &(dynamic_cast<placeholder<T>*>(_content)->_val);
    }
    Any & swap(Any & other)
    {
        std::swap(_content,other._content);
        return *this;
    }

    //赋值运算符的重载
    template <class T>
    Any & operator=(const T & val)
    {
        Any(val).swap(*this);
        return *this;
    }

    Any & operator=(Any other)
    {
        other.swap(*this);
        return *this;
    }
private:
    class holder
    {
    public:
        virtual ~holder(){}
        virtual const std::type_info & type() = 0;
        virtual holder * clone() = 0;
    };

    template<class T>
    class placeholder: public holder
    {
    public:
        placeholder(const T & val):_val(val){}
        //获取子类存储的对象类型
        virtual  const std::type_info & type() {return typeid(T); }
        //针对当前对象克隆一个新的子类对象
        virtual holder * clone() { return new placeholder<T>(_val);}
        T _val;
    };
    holder * _content;
};

class Test
{
public:
    Test() {std::cout<<"构造函数"<<std::endl;}
    Test(const Test & t) {std::cout<<"拷贝构造"<<std::endl;}
    ~Test() {std::cout<<"析构函数"<<std::endl;}
};


int main()
{
    Any a;
    {
        Test t;
        a = t;
    }
    a = 10;
    int * pa = a.get<int>();
    std::cout<<*pa<<std::endl;
    a = std::string("hello");
    std::string * ps = a.get<std::string>();
    std::cout<<*ps<<std::endl;
    while(true) sleep(1);
    // std::any a;
    // a = 10;
    // int * p1 = std::any_cast<int>(&a);
    // int p2 = std::any_cast<int>(a);
    // std::cout<<*p1<<":"<<p2<<std::endl;
    // a = std::string("world");
    // std::string * ps = std::any_cast<std::string>(&a);
    // std::string ps2 = std::any_cast<std::string>(a);
    // std::cout<<*ps<<":"<<ps2<<std::endl;
    return 0;
}